package com.hk.Mgr.web.controller.common;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.hk.app.utils.RedisUtils;
import com.hk.app.utils.SendMsgCilent;
import com.hk.commons.*;
import com.hk.commons.entity.Parameter;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.utils.MsgTypeConstants;
import com.hk.commons.vo.CheckInfo;
import com.hk.service.IPush;
import com.hk.service.order.IOrderMonitor;
import com.hk.service.order.IParameter;
import com.hk.service.sys.ISysUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hk.commons.ConstantFYJZH;
import com.hk.commons.ConstantOrderStatus;
import com.hk.commons.ConstantPayment;
import com.hk.commons.HqlFilter;
import com.hk.commons.StringHelper;
import com.hk.commons.entity.order.OrderInfo;
import com.hk.commons.entity.sys.SysUser;
import com.hk.service.kyc.ICoupon;
import com.hk.service.kyc.IUserCard;
import com.hk.service.order.IOrderHandle;
import com.hk.service.order.IOrderInfo;
import com.hk.service.product.IProductInfo;

@Controller
@RequestMapping(value = "/hk" + "/RMICtr")
public class RMICtr {
    public static final int REFUND_STATUS = 5;

    private Logger logger = LoggerFactory.getLogger(RMICtr.class);

    @Autowired
    private IOrderInfo orderInfoService;

    @Autowired
    private IProductInfo productService;

    @Autowired
    private IOrderHandle<OrderInfo> hkOrderHandleImpl;

    @Autowired
    ICoupon couponService;

    @Autowired
    private JdbcTemplate jdbcTemplate;
    private String ownSign = "inner";

    @Autowired
    private IOrderMonitor orderMonitorRepo;

    @Autowired
    private IProductInfo prodService;

    @Autowired
    private IPush pushService;

    @Autowired
    private IParameter parameterServices;

    @Autowired
    public ISysUser userService;

    @Autowired
    private SendMsgCilent sendMsgCilent;


    @ResponseBody
    @RequestMapping(value = "/getPaybackOrderList", method = RequestMethod.GET)
    public List<OrderInfo> getAllChannelList(HttpServletRequest request) {
        String sign = request.getParameter("sign");
        if (ownSign.equals(sign)) {
            List<OrderInfo> orderList = orderInfoService.findPayBackOrders(
                    ConstantOrderStatus.CONFIRM_STATUS__TRUE,
                    ConstantOrderStatus.PAY_STATUS_TRUE,
                    Long.valueOf(ConstantPayment.FYJZH_PAY));
            return orderList;
        } else {
            logger.info("非法请求getPaybackOrderList");
            return null;
        }
    }

    @ResponseBody
    @RequestMapping(value = "/getProdNewStartOrders", method = RequestMethod.GET)
    public List<OrderInfo> getProdNewStartOrders(HttpServletRequest request) {
        String sign = request.getParameter("sign");
        if (ownSign.equals(sign)) {
            List<OrderInfo> orderList = orderInfoService
                    .getProdNewStartOrders();
            logger.info("请求getProdNewStartOrders size = "
                    + (orderList == null ? 0 : orderList.size()));
            return orderList;
        } else {
            logger.info("非法请求getProdNewStartOrders");
            return null;
        }
    }

    @ResponseBody
    @RequestMapping(value = "/updateOrder", method = RequestMethod.POST)
    public boolean updateOrder(@RequestBody OrderInfo order,
                               HttpServletRequest request) {
        String sign = request.getParameter("sign");
        if (ownSign.equals(sign)) {
            try {
                orderInfoService.update(order);
                return true;
            } catch (Exception e) {
                logger.info("远程调用updateOrder更新异常!orderId={}", order.getId());
                logger.error("远程调用updateOrder更新异常!", e);
                return false;
            }

        } else {
            logger.info("非法请求updateOrder");
            return false;
        }
    }


    /**
     * 预授权失败，取消订单
     *
     * @param order
     * @param request
     * @return
     */
    //@ResponseBody
    //@RequestMapping(value = "/cancelOrder", method = RequestMethod.POST)
    public boolean cancelOrder(@RequestBody OrderInfo order,
                               HttpServletRequest request) {

        logger.info("预授权失败，取消订单!orderId={}", order.getId());
        String sign = request.getParameter("sign");
        if (!ownSign.equals(sign)) {
            logger.info("非法请求cancelOrder");
            return false;
        }

        try {
            String keyStr = ConstantsOrder.ORDER_FYJZH_PRIX + order.getId();
            OrderInfo orderInRedis = RedisUtils.getOrderInfo(keyStr);

            if (orderInRedis != null) {
                returnCoupon(order);

                logger.info("预授权失败，删除redis里的订单  key={} orderInfo={} ", keyStr, JsonUtils.toJson(orderInRedis));
                RedisCilent.delKey(keyStr);

                orderMonitorRepo.cancel(order.getId(), JsonUtils.toJson(orderInRedis));
            }

            return true;
        } catch (Exception e) {
            logger.info("远程调用cancelOrder更新异常!orderId={}", order.getId());
            logger.error("远程调用cancelOrder更新异常!", e);
            return false;
        }
    }

    /**
     * 预授权失败，取消订单
     *
     * @param order
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/refundOrder", method = RequestMethod.POST)
    public boolean refundOrder(@RequestBody OrderInfo order,
                               HttpServletRequest request) {

        Long orderId = order.getId();
        logger.info("反预授权失成功，订单进行退款! orderId={}", orderId);
        String sign = request.getParameter("sign");
        if (!ownSign.equals(sign)) {
            logger.info("非法请求:refundOrder");
            return false;
        }

        try {
            String keyStr = ConstantsOrder.ORDER_FYJZH_PRIX + orderId;
            OrderInfo orderInRedis = RedisUtils.getOrderInfo(keyStr);

            if (orderInRedis == null) {
                logger.error("订单进行退款，订单不存在在缓存里! orderId={}", orderId);
                return false;
            }

            OrderInfo orderInDB = orderInfoService.findById(orderId);
            if (orderInDB == null) {
                logger.error("订单进行退款，订单不存在在数据库里! orderId={}", orderId);
                return false;
            }

            if (orderInDB.getConfirmStatus().equals(REFUND_STATUS) && orderInDB.getPayStatus().equals(REFUND_STATUS)) {
                logger.error("订单进行退款,已进行过退款,不能重复退款! orderId={}", orderId);
                return false;
            }

            logger.info("订单进行退款 key={} orderInfo={} ", keyStr, JsonUtils.toJson(orderInRedis));
            //退换加息券
            returnCoupon(order);

            HashMap orderSnapshot = getOrderSnapShot(orderId, orderInDB);

            orderInDB.setConfirmStatus(REFUND_STATUS);
            orderInDB.setPayStatus(REFUND_STATUS);
            orderInDB.setContractUrl(null);
            orderInDB.setContractUrlHTML(null);
            orderInfoService.update(orderInDB);

            orderMonitorRepo.refund(orderId, JsonUtils.toJson(orderSnapshot));

            notifyCustomer(orderInDB);

            return true;
        } catch (Exception e) {
            logger.info("远程调用refundOrder更新异常! orderId={}", orderId);
            logger.error("远程调用refundOrder更新异常!", e);
            return false;
        }
    }

    private void notifyCustomer(OrderInfo orderInDB) {
        ProductInfo productInfo = productService.findById(orderInDB.getProductId());

        SysUser userInfo = userService.findById(orderInDB.getUserId());
        if(userInfo == null){
            return ;
        }

        String mobile = userInfo.getName();

        pushRefundResultToCustomer(
                StringHelper.myformat.format(orderInDB.getSuccessAmount()),
                productInfo.getName(),
                mobile);

    }

    private void pushRefundResultToCustomer(String amt, String productName, String phone) {
        String msg = String.format("您本次投资的一笔%s元的%s，投资失败，可重新进行投资操作!", amt, productName);

        // 您已成功购买一笔50000元的久恒福海（180天）002，请到投资资产或交易记录中查看
        if (StringHelper.isNotEmpty(phone)) {
            Boolean pushResult =pushService.jgPushCustomerMsg(
                    msg, "购买失败", null, null, null, phone, ConstantPush.PUSH_MENU_ORDER, MsgTypeConstants.BUY);

            if(!pushResult){
                logger.error(phone+" 下单失败消息推送失败!! ");
            }
        }

        Parameter params = parameterServices.getByName(CacheConstants.ORDER_REFUND_SEND_SMS_PUSH);
        if (params != null) {
            StringBuffer content = new StringBuffer();
            content.append(params.getValue01());
            content.append(msg);
            content.append(params.getValue02());
            Boolean sendResult = sendMsgCilent.sendMsgContentCustom(phone, String.valueOf(content));

            if(!sendResult){
                logger.error(phone+" 下单失败短信推送失败!! ");
            }
        }

    }

    private HashMap getOrderSnapShot(Long orderId, OrderInfo orderInDB) {
        HashMap orderSnapshot = new HashMap();
        orderSnapshot.put("orderId", orderId);
        orderSnapshot.put("confirmStatus", orderInDB.getConfirmStatus());
        orderSnapshot.put("payStatus", orderInDB.getPayStatus());
        orderSnapshot.put("contractUrl", orderInDB.getContractUrl());
        orderSnapshot.put("contractUrlHTML", orderInDB.getContractUrlHTML());
        return orderSnapshot;
    }

    private void returnCoupon(OrderInfo order) {
        if (order.getUserCardId() == null) {
            logger.error("返回卡券失败 没有需要返回的卡券 userCardId={} ", order.getUserCardId());
            return;
        }

        OrderInfo orderInDB = orderInfoService.findById(order.getId());
        if (orderInDB == null || orderInDB.getUserCardId() == null) {
            logger.error("返回卡券失败 订单或卡券不存在 userCardId={} ", order.getUserCardId());
            return;
        }

        logger.info("返回卡券  userCardId={} ", order.getUserCardId());
        couponService.activeCoupon(order.getUserCardId(), order.getUserId(), order.getId(), false);
    }


    @ResponseBody
    @RequestMapping(value = "/saveOrder", method = RequestMethod.POST)
    public boolean saveOrder(@RequestBody OrderInfo order, HttpServletRequest request) {
        logger.info("远程调用saveOrder方法!orderId={}", order.getId());
        String sign = request.getParameter("sign");

        if (!ownSign.equals(sign)) {
            logger.info("非法请求saveOrder");
            return false;
        }

        try {
            boolean updateProductAmountResult = this.updateProductAmount(order);

            if (!updateProductAmountResult) {
                return false;
            }

            logger.info("远程调用saveOrder方法 before add order {}", order.getId());
            orderInfoService.add(order);
            logger.info("远程调用saveOrder方法 after add order {}", order.getId());

            if (order.getUserCardId() != null) {
                couponService.activeCoupon(order.getUserCardId(), order.getUserId(), order.getId(), true);
            }

            boolean saveRouteResult = this.saveRouteOrder(order, request);
            if (!saveRouteResult) {
                return false;
            }

        } catch (Exception e) {
            logger.info("远程调用saveOrder更新异常!orderId={}", order.getId());
            logger.error("远程调用saveOrder更新异常!", e);
            return false;
        }

        return true;
    }

    //    @ResponseBody
//    @RequestMapping(value = "/saveRouteOrder", method = RequestMethod.POST)
    public boolean saveRouteOrder(@RequestBody OrderInfo order, HttpServletRequest request) {
        logger.info("saveRouteOrder!orderId={}", order.getId());
        String sign = request.getParameter("sign");

        if (!ownSign.equals(sign)) {
            logger.info("非法请求saveRouteOrder");
            return false;
        }

        try {
            logger.info("saveRouteOrder before createOrderRoute  ");
            hkOrderHandleImpl.createOrderRoute(order.getUserId(), order.getId(), order.getCompanyId());
            logger.info("saveRouteOrder after createOrderRoute  ");
        } catch (Exception e) {
            logger.info("远程调用saveRouteOrder更新异常!orderId={}", order.getId());
            logger.error("远程调用saveRouteOrder更新异常!", e);
            return false;
        }

        return true;
    }


    private synchronized boolean updateProductAmount(OrderInfo order) {
        Long orderId = order.getId();
        ;
        try {
            //调用同步方法更改产品额度
            Long productId = order.getProductId();

            BigDecimal amount = order.getSuccessAmount();

            orderMonitorRepo.updateProductStarted(orderId);

            CheckInfo checkInfo = prodService.checkLimit(order.getUserId(), order.getProductId(), order.getSuccessAmount());

            if (!checkInfo.getResult()) {
                logger.error(checkInfo.getResultMsg());

                orderMonitorRepo.updateProductFailed(orderId, checkInfo.getResultMsg());
                return false;
            }

            logger.info("UPDATE_PRODUCT_AMOUNT START:  productId={}, amount={} , orderId={} ", productId, amount, orderId);
            Boolean result = prodService.updAmountByPay(productId, amount, true);

            orderMonitorRepo.updateProductFinish(orderId);

            return result;
        } catch (Exception ex) {
            logger.error("更改产品额度失败 : " + ex.getMessage());

            orderMonitorRepo.updateProductFailed(orderId, ex.getMessage());

            return false;
        }
    }

    /**
     * 获取冻结资产的笔数
     *
     * @param request
     * @return
     */

    @ResponseBody
    @RequestMapping(value = "/getDJOrderAccount", method = RequestMethod.POST)
    public Long getDJOrderAccount(@RequestBody SysUser req,
                                  HttpServletRequest request) {
        String sign = request.getParameter("sign");
        Long userId = req.getId();

        logger.info("请求getDJOrderAccount userId = {}", userId);
        if (ownSign.equals(sign)) {
            HqlFilter hqlFilter = new HqlFilter();
            hqlFilter.addEQFilter("userId", userId);
            hqlFilter.addEQFilter("payStatus",
                    ConstantOrderStatus.PAY_STATUS_TRUE);
            hqlFilter.addEQFilter("confirmStatus ",
                    ConstantOrderStatus.CONFIRM_STATUS__NO_CONFIRM);
            hqlFilter.addSort("orderCreatedOn");
            hqlFilter.addOrder("desc");
            logger.info("getDJOrderAccount hqlFilter = "
                    + hqlFilter.getWhereAndOrderHql());
            Long size = orderInfoService.countByFilter(hqlFilter);

            logger.info("请求getDJOrderAccount size = " + size);
            return size;
        } else {
            logger.info("非法请求getDJOrderAccount");
            return null;
        }
    }


    /**
     * 获取金账户待回款订单
     *
     * @param
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getPayBackOrders", method = RequestMethod.GET)
    public List<Map<String, Object>> getPayBackOrders(
            HttpServletRequest request) {
        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        String sign = request.getParameter("sign");
        String productId = request.getParameter("productId");
        if (ownSign.equals(sign) && StringHelper.isNotEmpty(productId)) {
            String sql = "select s.Name,o.payBackAmt,o.id,o.userId,o.contract_no from SysUser s,t_order_info o where o.userId=s.Id and o.payStatus=" + ConstantOrderStatus.PAY_STATUS_TRUE + " and o.confirmStatus=" + ConstantOrderStatus.CONFIRM_STATUS__TRUE + " and o.productId=" + productId + " and o.paymentId=" + ConstantPayment.FYJZH_PAY;
            try {
                List<Map<String, Object>> queryList = jdbcTemplate.queryForList(sql);
                resultList = queryList;
            } catch (Exception e) {
                logger.info("获取待回款订单异常!sql={}", sql);
                logger.error("获取待回款订单异常!", e);
            }
        }
        return resultList;
    }


}
